//  Copyright (c) Microsoft Corporation.  All Rights Reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

using System.IdentityModel.Selectors;

namespace Saml20
{
    public class Saml20Action
    {
        string name;
        string ns;
        bool isReadOnly = false;

        public Saml20Action()
        {
        }

        public Saml20Action(string name, string ns)
        {
            if (String.IsNullOrEmpty(name))
                throw new ArgumentException("Argument 'name' cannot be null or empty.");
            if (String.IsNullOrEmpty(ns))
                throw new ArgumentException("Argument 'ns' cannot be null or empty.");

            this.name = name;
            this.ns = ns;
        }

        public Saml20Action(XmlReader reader, Saml20Serializer serializer, SecurityTokenSerializer keyInfoSerializer, SecurityTokenResolver outOfBandTokenResolver)
        {
            this.ReadXml(reader, serializer, keyInfoSerializer, outOfBandTokenResolver);
        }

        public string Name
        {
            get { return this.name; }
            set
            {
                if (this.isReadOnly)
                    throw new InvalidOperationException("The object is read-only.");

                if (String.IsNullOrEmpty(value))
                    throw new ArgumentException("Action name cannot be null or empty.");

                this.name = value;
            }
        }

        public string Namespace
        {
            get { return this.ns; }
            set
            {
                if (this.isReadOnly)
                    throw new InvalidOperationException("The object is read-only.");

                if (String.IsNullOrEmpty(value))
                    throw new ArgumentException("Action namespace cannot be null or empty.");

                this.ns = value;
            }
        }

        void CheckObjectValidity()
        {
            if (String.IsNullOrEmpty(this.ns) || String.IsNullOrEmpty(this.name))
                throw new InvalidOperationException("saml:Action should have both name and namespace specified.");
        }

        public void MakeReadOnly()
        {
            if (!this.isReadOnly)
            {
                this.isReadOnly = true;
            }
        }

        public virtual void ReadXml(XmlReader reader, Saml20Serializer serializer, SecurityTokenSerializer keyInfoSerializer, SecurityTokenResolver outOfBandTokenResolver)
        {
            if (reader == null)
                throw new ArgumentNullException("reader");

            this.ns = reader.GetAttribute(Saml20Constants.NamespaceAttribute);
            if (String.IsNullOrEmpty(this.ns))
                throw new SecurityTokenException("<saml:Action> element requires a valid 'Namespace' attribute.");

            reader.MoveToContent();
            this.name = reader.ReadString();

            reader.ReadEndElement();
        }

        public virtual void WriteXml(XmlWriter writer, SecurityTokenSerializer tokenSerializer)
        {
            CheckObjectValidity();

            if (writer == null)
                throw new ArgumentNullException("reader");

            writer.WriteStartElement(Saml20Constants.Action, Saml20Constants.Namespace);
            writer.WriteAttributeString(Saml20Constants.NamespaceAttribute, this.ns);
            writer.WriteString(this.name);
            writer.WriteEndElement();
        }

    }

}
